#pragma once

#include<Windows.h>
#include "ByteQueue.h"

#define READ_BUFF_LEN 128

class ThreadedComport;

typedef struct{
	OVERLAPPED o;
	ThreadedComport* caller;
}OVERLAPPEDEX;

class ThreadedComport
{
	private:
		BOOL _isOpen;
		HWND notifyTo;
	public:
		BOOL fWaittingOnRead, fKeepReading;
		HANDLE _hCom;
		HANDLE _hEventWriteDone;
		HANDLE _hEventReadDone;
		HANDLE hReadingThread;
		OVERLAPPEDEX _send_overlapped;
		OVERLAPPEDEX _recieve_overlapped;

		/*buffer to read*/
		UCHAR write_buff[128];
		HANDLE write_mutex; //this is used to protect write_buffer
		UCHAR read_buff[READ_BUFF_LEN];
		ByteQueue *byte_queue;
		HANDLE read_mutex; //this is used to protect read_buffer
		DWORD wlen, rlen; 
		DCB dcb;


	public:
		ThreadedComport(void);
		~ThreadedComport(void);
		BOOL open(LPWSTR portName, DWORD baudrate, BYTE byteSize, BYTE parity);
		void setNotifyTo(HWND hwnd);
		BOOL close();
		void send_data();
		void recieve_data();
		inline BOOL isOpen(){return _isOpen;};
		void stopReading();

		static VOID WINAPI recieve_thread_routine(PVOID param);
		static void WINAPI _send_callback(DWORD _dwErrorCode, DWORD dwNumberOfByte, LPOVERLAPPED lpOverlapped);
};